layui.define(['newTable', 'jquery', 'form', 'xmSelect','laytpl'], function (exports) {
    "use strict";
    let MOD_NAME = 'tableEdit',
        $ = layui.jquery,
        table = layui.newTable,
        form = layui.form,
        xmSelect = layui.xmSelect,
        laytpl = layui.laytpl,
        tableEdit = {
            v: "1.0.0",
            config: {
                tableId: '',//目标tableID
                tableObj: null,//渲染后的table对象 tableId 和 tableObj 二选一
                addEmptyRow: true,//是否自动添加空行
                emptyRowData: {},//空行数据，请根据表格数据格式添加
                rowEditChange: null,// function (data, field) { },//编辑数据改变时回调 当 editRow="customer" 触发回调
                rowEditCustomer: null,//function (field, rowData) { return null; },//自定义编辑框渲染，返回Jquery对象
                rowEditRender: null,//function (field, inputId, rowData) { }//自定义渲染编辑框时回调 当 editRow="customer" 触发回调
            }
        },
        thisEdit = function () {
            let that = this;
            return {
                render: function (options) {
                    let inst = new editClass($.extend({}, that.config, options));
                    return thisEdit.call(inst);
                },
                reload: function (data) {
                    that.reload.call(that, data);
                },
                addEmptyRow: function () {
                    that.addEmptyRow.call(that);
                },
                data: function () {
                    return that.getData();
                },
                config: that.config
            }
        },
        editClass = function (options) {
            let that = this;
            that.config = $.extend({}, that.config, tableEdit.config, options);
            that.render();
        };
    editClass.prototype.render = function (options) {
        if (!this.config.tableId && !this.config.tableObj) return;
        let that = this,
            tableId = that.config.tableId;
        that.tableObj = this.config.tableObj ? this.config.tableObj : table.reload(tableId);
        let data = table.cache[tableId],
            cols = that.tableObj.config.cols,
            style = '    position: absolute;\n' +
                '    width: 90%;\n' +
                '    height: 90%;\n' +
                '    padding: 0;\n' +
                '    border-radius: 0;\n' +
                '    top: 0;\n' +
                '    left: 0;\n' +
                '    right: 0;\n' +
                '    bottom: 0;\n' +
                '    margin: auto;',
            createSelect = function (inputId, val, one) {
                let div = $('<div class="editRowExt" style="' + style + ';padding:0;"></div>');
                let select_dom = $("<div id=\"" + inputId + "\" style='border-bottom: 0px solid #E6E6E6;'></div>");
                div.append(select_dom);
                return div;
            }
            ,createSwitch= function (inputId, val, one) {
                let div = $('<div class="editRowExt" style="' + style + ';padding:0;"></div>');
                let select_dom = $('<input type="checkbox" value="" lay-skin="switch" lay-text="启用|禁用" lay-filter="'+inputId+'" />');
                if(val == 1){
                    select_dom.attr("checked","checked");
                }
                div.append(select_dom);
                return div;
            }
            , createCustomerInput = function (inputId, val, one) {
                return $('<input autocomplete="off" id="' + inputId + '" value="' + val + '" type="text" class="layui-input" style="' + style + '"/>');
            },
            createNumberInput = function (inputId, val, one) {
                return $('<input autocomplete="off" id="' + inputId + '" value="' + val + '" type="text" class="layui-input" style="' + style + '" onkeyup="value=value.replace(/[^\\d]/g,\'\')"/>');
            },
            createFloatInput = function (inputId, val, one) {
                return $('<input autocomplete="off" id="' + inputId + '" value="' + val + '" type="text" class="layui-input" style="' + style + '" onkeyup="if(isNaN(value))execCommand(\'undo\')"/>');
            },
            changeData = function (tableId, row, field,newVal){
                table.cache[tableId][row][field] = newVal;
                console.log("修改数据："+table.cache[tableId][row][field]);
            },
            inputChange = function ($input, row, field) {
                let rowData = table.cache[tableId][row];
                $input.bind("input propertychange", function (event) {
                    let newVal = $input.val();
                    changeData(tableId,row,field,newVal);
                    if (that.config.rowEditChange) {
                        let addNewRow = that.config.rowEditChange.call(that, rowData, field, newVal);
                        if (addNewRow && row == data.length - 1)
                            return that.addEmptyRow(), false;
                    }
                });
                /*$input.change(function () {

                    // that.reload();
                });*/
            };
        if (this.config.rowNum) {
            let one_data = data[this.config.rowNum - 1];
            data = [];
            data.push(one_data);
        }
        if (data && data.length > 0)
            for (let i = 0; i < data.length; i++) {
                //循环字段
                let rowData = data[i],
                    row = rowData.LAY_TABLE_INDEX;

                rowData["rowEdit"] = true;
                $.each(cols, function (n, oneCol) {
                    $.each(oneCol, function (nn, one) {
                        if (!one.field) return true;
                        if (!one.editRow) return true;

                        let editRow = one.editRow;

                        if(typeof(one.editRow) == "function"){
                            editRow = one.editRow(rowData);
                        }

                        let $td = $("div[lay-id='" + tableId + "'] tr[data-index='" + row + "'] td[data-field='" + one.field + "']"),
                            createFunc;
                        switch (editRow) {
                            case "render":
                                //重新刷新当前数据
                                if(one.toolbar){
                                    $td.find("div").html(laytpl($(one.toolbar).html()||'').render(rowData));
                                }
                                break;
                            case "customer":
                                if (that.config.rowEditCustomer) {
                                    let div = $('<div class="editRowExt" style="' + style + ';padding:0;"></div>');
                                    let $obj = that.config.rowEditCustomer(one.field, rowData, one, row, div);
                                    if ($obj) {
                                        div.append($obj);
                                        $td.append(div);
                                        if (layui.form) {
                                            layui.form.render();
                                        }
                                        if (one.editRow == "customer" && that.config.rowEditRender) {
                                            let inputId = 'rowedit_' + tableId + '_' + one.field + '_' + row;
                                            that.config.rowEditRender.call(that, one.field, inputId, rowData, one, row);
                                        }
                                        break;
                                    }
                                }
                                createFunc = createCustomerInput;
                                break;
                            case "number":
                                createFunc = createNumberInput;
                                break;
                            case "float":
                                createFunc = createFloatInput;
                                break;
                            case "select":
                                createFunc = createSelect;
                                break;
                            case "switch":
                                createFunc = createSwitch;
                                break;
                        }
                        if (createFunc) {
                            let inputId = 'rowedit_' + tableId + '_' + one.field + '_' + row,
                                $input = createFunc(inputId, rowData[one.field] == undefined ? "" : rowData[one.field], one);

                            $td.append($input);

                            switch (editRow) {
                                case "switch":
                                    form.render();
                                    //获取对应的数据
                                    form.on('switch('+inputId+')', function (obj) {
                                        // layer.tips(obj.elem.checked, obj.othis);
                                        if(obj.elem.checked){
                                            changeData(tableId,row,one.field,1);
                                        }else{
                                            changeData(tableId,row,one.field,0);
                                        }
                                    });
                                    break;
                                case "select":
                                    let def_op = {
                                        theme: {
                                            color: localStorage.getItem("theme-color-color"),
                                        },
                                        toolbar: {
                                            show: false,
                                        },
                                        prop: {
                                            name: 'name',
                                            value: 'value',
                                        },
                                        filterable: false,
                                        radio: true,
                                        el: '#' + inputId,
                                        data: [],
                                        direction: 'down',
                                        clickClose: true,
                                        on: function (data) {
                                            let sel_arr = data.arr;
                                            let values = [];
                                            $.each(sel_arr, function (index, item) {
                                                values.push(item.value);
                                            })
                                            let value = values.join(",");
                                            changeData(tableId,row,one.field,value);
                                        },
                                        show: function () {

                                            $("[lay-id=" + tableId + "] .layui-table-box").css("overflow", "inherit");
                                            $("[lay-id=" + tableId + "] .layui-table-body").css("overflow", "inherit");
                                        },
                                        hide: function () {
                                            $("[lay-id=" + tableId + "] .layui-table-box").css("overflow", "");
                                            $("[lay-id=" + tableId + "] .layui-table-body").css("overflow", "");
                                        }
                                    }
                                    let op = $.extend({}, def_op, one.option);
                                    let sel = xmSelect.render(op);
                                    if(rowData[one.field]!=undefined){
                                        sel.setValue(new String(rowData[one.field]).split(","))
                                    }
                                    break;
                                default:
                                    inputChange($input, row, one.field);

                            }
                            if (editRow == "customer" && that.config.rowEditRender) {
                                that.config.rowEditRender.call(that, one.field, inputId, rowData, one, row);
                            }
                        }
                    });
                });
            }
        else if (that.config.addEmptyRow)
            that.addEmptyRow();
        return that;
    }
    //添加空行
    editClass.prototype.addEmptyRow = function () {
        this.tableObj.config.data.push(this.config.emptyRowData);
        this.reload();
    }
    //重载表格
    editClass.prototype.reload = function (data) {
        data = data || this.tableObj.config.data;
        if (data && data.length > 0) {
            if (this.config.addEmptyRow) {
                //判断是否存在空行
                let lastRow = data[data.length - 1], haveEmptyRow = true;
                $.each(this.config.emptyRowData, function (key, val) {
                    if (lastRow[key] != val)
                        return haveEmptyRow = false, false;
                });
                if (!haveEmptyRow)
                    data.push(this.config.emptyRowData);
            }
        }
        let tableId = this.config.tableId;
        table.reload(tableId, {data: data});
        this.render();
    }
    //获取编辑数据
    editClass.prototype.getData = function () {
        let d = JSON.parse(JSON.stringify(table.cache[this.tableObj.config.id]));
        for (let i = d.length - 1; i >= 0; i--) {
            let one = d[i];
            if (one.length == 0)
                d = d.splice(i, 1);
            else {
                one.row = one.LAY_TABLE_INDEX + 1;
                delete one.LAY_TABLE_INDEX;
            }
        }
        //排除空行
        if (this.config.addEmptyRow)
            d.splice(d.length - 1, 1);
        return d;
    }
    //核心入口
    tableEdit.render = function (options) {
        let inst = new editClass(options);
        return thisEdit.call(inst);
    };

    // 判断一个串实际长度（1个中文2个单位）
    function lengthText(txtValue) {
        if (typeof txtValue != "string") {
            txtValue = "" + txtValue + "";
        }
        var cArr = txtValue.match(/[^\x00-\xff]/ig);
        return txtValue.length + (cArr == null ? 0 : cArr.length);
    }

    function verifyModule (cols,row){
        let errors = [];
        function v (verify){
            let verify_obj = verify.verify;
            if(typeof (verify_obj) == "function"){
                verify_obj = verify_obj(row);
            }
            $.each(verify_obj,function (key,value){
                let date_value = row[verify.field];
                if(key == "required"){
                    if(value == true){
                        if((date_value == undefined || date_value == "")){
                            errors.push({
                                row:row.LAY_TABLE_INDEX,
                                field:verify.field,
                                title:verify.title,
                                msg:"必须填写"
                            })
                        }
                    }
                }else if(key == "reg"){
                    if(date_value != undefined && date_value != null && date_value!=''){
                        if(!value.expression.test(date_value)){
                            errors.push({
                                row:row.LAY_TABLE_INDEX,
                                field:verify.field,
                                title:verify.title,
                                msg:value.msg
                            })
                        }
                    }
                }else if(key == "email"){
                    if(value == true){
                        if(date_value != undefined && date_value != null && date_value!=''){
                            if(!/^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(date_value)){
                                errors.push({
                                    row:row.LAY_TABLE_INDEX,
                                    field:verify.field,
                                    title:verify.title,
                                    msg:"邮件格式不正确(xxx@xx.xxx)"
                                })
                            }
                        }

                    }
                }else if(key == "telephone"){
                    if(value == true){
                        if(date_value != undefined && date_value != null && date_value!='') {
                            if(!/((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)/.test(date_value)){
                                errors.push({
                                    row:row.LAY_TABLE_INDEX,
                                    field:verify.field,
                                    title:verify.title,
                                    msg:"电话格式不正确(支持手机号码，3-4位区号，7-8位直播号码，1－4位分机号)"
                                })
                            }
                        }

                    }
                }else if(key == "size"){
                    if(date_value != undefined && date_value != null) {
                        let s_len = lengthText(date_value);
                        if (s_len >= value.min && s_len <=value.max) {

                        }else{
                            errors.push({
                                row:row.LAY_TABLE_INDEX,
                                field:verify.field,
                                title:verify.title,
                                msg:'输入的字符串必须再'+value.min+'到' + value.max + '个字符!'
                            })
                        }
                    }
                }
            })
        }

        $.each(cols,function (key,value){
            v(value);
        })
        return errors;
    }
    function mScroll($div,doc) {
        $div.stop(true);
        $div.animate({scrollTop: doc.offset().top - 100}, 510);
    }

    tableEdit.serverError = function (tableObj,msg_str){
        let config = tableObj.config;
        let list = [];
        if(config.isEdit != true){
            $.each(table.cache[config.id],function (row,item){
                if(item.add == true){
                    list.push(item);
                }
            })
        }else {
            list = table.cache[config.id];
        }
        let msg = JSON.parse(msg_str);
        $.each(msg,function (key,value){
            let f_arr = key.split(".");
            console.log(f_arr[0],f_arr[1],value)
            try {
                let a = $("#rowedit_"+config.id+"_"+f_arr[1]+"_"+eval(f_arr[0]).LAY_TABLE_INDEX);
                layer.tips(value, a, {
                    time: 3000,
                    tips: [2, "#FF5722"],
                    tipsMore: true
                });
                mScroll($("[lay-id='" + config.id + "'] .layui-table-main"),a);
            } catch (e) {
            }
            return false;
        })
    }
    tableEdit.verifyData = function (tableObj){
        let errors = [];
        let config = tableObj.config;
        let list_data = table.cache[config.id];
        let cols = {};
        //找到需要校验的类型
        $.each(config.cols[0],function (index,item){
            if(item.verify != undefined && item.field!=undefined && item.field!=''){
                cols[item.field] = item;
            }
        })

        console.log(list_data,"待保存的数据");
        console.log(cols,"列校验");
        $.each(list_data,function (index,item){
            console.log(item,"校验中")
            let error_row = verifyModule(cols,item);
            errors = errors.concat(error_row);
        })
        console.log(errors,"校验结束")
        $.each(errors,function (index,item){
            try {
                let a = $("#rowedit_"+config.id+"_"+item.field+"_"+item.row);
                // $("[lay-id='" + config.id + "'] .layui-table-body").animate({scrollLeft: a.offset().left - 100}, 1000);
                setTimeout(function (){
                    layer.tips(item.msg, a, {
                        time: 3000,
                        tips: [2, "#FF5722"],
                        tipsMore: true
                    });
                },550)
                mScroll($("[lay-id='" + config.id + "'] .layui-table-main"),a);
            } catch (e) {

            }
            return false;
        })
        if(errors.length > 0){
            return false;
        }
        return true;
    }
    exports(MOD_NAME, tableEdit);
});
